﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using AgnisDAL.ServiceAgnis;
using AgnisEbmtTranslator.DataSets;
using AgnisEbmtTranslator.Properties;
using EbmtDAL;
using Form = AgnisDAL.ServiceAgnis.Form;

namespace AgnisEbmtTranslator
{

    #region TRANSLATION

    /// <summary>
    ///   Main translation class providing the methods used to translate data.
    /// </summary>
    public class TranslatorProcess
    {
        #region Local members declaration

        public enum AgnisForm2450DuePeriods
        {
            Null = 0,
            HundredDays = 1,
            SixtMonths = 2,
            Annual = 3
        }

        private static string textReport;
        private static string textReport2;
        private static readonly MappingDataSet dsMappingInfo = new MappingDataSet();
        private AgnisForm2450DuePeriods currentAgnisFormDuePeriod;
        public DateTime dateOfTransplant;
        //Original dataset.
        public DataSet dsEbmtPatientG = new DataSet();
        //Filtered dataset.
        public DataSet dsFilteredEbmtPatientG;
        //Main IDs for treatment:
        public int patientID;
        public int patientIDAA;

        #endregion

        #region Constructor

        public TranslatorProcess(String ebmtConnectionString, String mappingInfoConnectionString)
        {
            EbmtDAL.EbmtDAL.SetCurrentEbmtDbConnectionString(ebmtConnectionString);
            MappingInfoDAL.SetCurrentMappingInfoConnectionString(mappingInfoConnectionString);
            //We load the mapping information for this form.
            MappingInfoDAL.LoadMappingInfo(dsMappingInfo);
            //We load the structure information for the agnis_forms.
            MappingInfoDAL.LoadAgnisFormsInfo(dsMappingInfo);
        }

        #endregion

        #region Methods to call the translation process

        /// <summary>
        ///   Generates an Agnis form for a given EBMT Patient.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient's Center ID </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient's ID on this center. </param>
        /// <param name="ebmtDateOfTransplant"> The date of transplant. </param>
        /// <param name="agnisPaperFormNumber"> The AGNIS paper form number. </param>
        /// <param name="agnisFormPublicID"> The AGNIS form Public ID. </param>
        /// <param name="agnisFormVersion"> The AGNIS form version. </param>
        /// <param name="agnisFormDuePeriod"> The AGNIS form due period. </param>
        /// <param name="instanceId"> Form instance Id </param>
        /// <param name="iCRID"> </param>
        /// <returns> An AGNIS FormRevision object </returns>
        public FormRevision GenerateAgnisFormForPatient(int ebmtPatientID, int ebmtPatientIDAA,
                                                        DateTime ebmtDateOfTransplant, int agnisPaperFormNumber,
                                                        int agnisFormPublicID, decimal agnisFormVersion,
                                                        AgnisForm2450DuePeriods agnisFormDuePeriod, string instanceId,
                                                        int iCRID)
        {
            EbmtDAL.EbmtDAL.recordsSelectionsList.Clear();
            switch (agnisPaperFormNumber)
            {
                case 2400: //Paper Form number for Pre-TED form.
                    if (ebmtPatientID > 0 && ebmtPatientIDAA > 0 &&
                        ebmtDateOfTransplant > DateTime.MinValue &&
                        agnisFormPublicID > 0 &&
                        agnisFormVersion > 0)
                    {
                        return GenerateForm2400(ebmtPatientID, ebmtPatientIDAA, ebmtDateOfTransplant, agnisFormPublicID,
                                                agnisFormVersion, instanceId);
                    }
                    throw new TranslationException("One or more of the arguments are not valid.");
                case 2450: //Paper Form number for Post-TED form.
                    if (ebmtPatientID > 0 && ebmtPatientIDAA > 0 &&
                        ebmtDateOfTransplant > DateTime.MinValue &&
                        agnisFormDuePeriod != AgnisForm2450DuePeriods.Null &&
                        agnisFormPublicID > 0 &&
                        agnisFormVersion > 0)
                    {
                        return GenerateForm2450(ebmtPatientID, ebmtPatientIDAA, ebmtDateOfTransplant, agnisFormPublicID,
                                                agnisFormVersion, agnisFormDuePeriod, instanceId);
                    }
                    throw new TranslationException("One or more of the arguments are not valid.");
                case 2900: //Paper Form number for ....
                    if (ebmtPatientID > 0 && ebmtPatientIDAA > 0 &&
                        agnisFormPublicID > 0 &&
                        agnisFormVersion > 0)
                    {
                        return GenerateForm2900(ebmtPatientID, ebmtPatientIDAA, ebmtDateOfTransplant, agnisFormPublicID,
                                                agnisFormVersion, instanceId);
                    }
                    throw new TranslationException("One or more of the arguments are not valid.");
                case 2804:
                    if (ebmtPatientID > 0 && ebmtPatientIDAA > 0 &&
                        ebmtDateOfTransplant > DateTime.MinValue &&
                        agnisFormPublicID > 0 &&
                        agnisFormVersion > 0 && iCRID == 0)
                    {
                        return GenerateForm2804(ebmtPatientID, ebmtPatientIDAA, ebmtDateOfTransplant, agnisFormPublicID,
                                                agnisFormVersion, instanceId);
                    }
                    throw new TranslationException("One or more of the arguments are not valid.");
                default:
                    return null;
            }
        }

        #region Form 2450 generation

        /// <summary>
        ///   Generate a new Agnis Form 2450 Post-TED form, for an EBMT patient passed as parameter.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient ID (center id owning this patient) </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient IDAA </param>
        /// <param name="ebmtDateOfTransplant"> The date of transplant </param>
        /// <param name="agnisFormPublicID"> The Agnis Form Public ID </param>
        /// <param name="agnisFormVersion"> The Agnis Form Version Number </param>
        /// <param name="agnisFormDuePeriod"> The due period (100days, 6month or annual issue) </param>
        /// <param name="instanceId"> </param>
        /// <returns> An AGNIS FormRevision object. </returns>
        public FormRevision GenerateForm2450(int ebmtPatientID, int ebmtPatientIDAA, DateTime ebmtDateOfTransplant,
                                             int agnisFormPublicID, decimal agnisFormVersion,
                                             AgnisForm2450DuePeriods agnisFormDuePeriod, string instanceId)
        {
            currentAgnisFormDuePeriod = agnisFormDuePeriod;
            switch (agnisFormDuePeriod)
            {
                case AgnisForm2450DuePeriods.HundredDays:
                    return GenerateHundredDayForm2450(ebmtPatientID, ebmtPatientIDAA, ebmtDateOfTransplant,
                                                      agnisFormPublicID, agnisFormVersion, instanceId);
                case AgnisForm2450DuePeriods.SixtMonths:
                    return GenerateSixtMonthForm2450(ebmtPatientID, ebmtPatientIDAA, ebmtDateOfTransplant,
                                                     agnisFormPublicID, agnisFormVersion);
                case AgnisForm2450DuePeriods.Annual:
                    return GenerateAnnualForm2450(ebmtPatientID, ebmtPatientIDAA, ebmtDateOfTransplant,
                                                  agnisFormPublicID, agnisFormVersion);
                default:
                    return null;
            }
        }

        /// <summary>
        ///   Generate a new Agnis Form 2450 Post-TED form for the hundred days report, for an EBMT patient passed as parameter.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient ID (center id owning this patient) </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient IDAA </param>
        /// <param name="ebmtDateOfTransplant"> The date of transplant </param>
        /// <param name="agnisFormPublicID"> The Agnis Form Public ID </param>
        /// <param name="agnisFormVersion"> The Agnis Form Version Number </param>
        /// <param name="instanceID"> </param>
        /// <returns> An AGNIS FormRevision object. </returns>
        public FormRevision GenerateHundredDayForm2450(int ebmtPatientID, int ebmtPatientIDAA,
                                                       DateTime ebmtDateOfTransplant, int agnisFormPublicID,
                                                       decimal agnisFormVersion, string instanceID)
        {
            //We load the patient ebmt data.
            patientID = ebmtPatientID;
            patientIDAA = ebmtPatientIDAA;
            dateOfTransplant = ebmtDateOfTransplant;
            dsEbmtPatientG = EbmtDAL.EbmtDAL.LoadPatientData(ebmtPatientID, ebmtPatientIDAA);
            //We initialize the objects used to create different patient data views.
            EbmtDAL.EbmtDAL.InitializePatientDataBindingSourcesG(dsEbmtPatientG);
            //We execute the translation process.
            return TranslateToAgnisForm(agnisFormPublicID, agnisFormVersion, instanceID);
        }

        /// <summary>
        ///   Generate a new Agnis Form 2450 Post-TED form for the 6 months report, for an EBMT patient passed as parameter.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient ID (center id owning this patient) </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient IDAA </param>
        /// <param name="ebmtDateOfTransplant"> The date of transplant </param>
        /// <param name="agnisFormPublicID"> The Agnis Form Public ID </param>
        /// <param name="agnisFormVersion"> The Agnis Form Version Number </param>
        /// <returns> An AGNIS FormRevision object. </returns>
        public FormRevision GenerateSixtMonthForm2450(int ebmtPatientID, int ebmtPatientIDAA,
                                                      DateTime ebmtDateOfTransplant, int agnisFormPublicID,
                                                      decimal agnisFormVersion)
        {
            //TODO: This Form issue needs still to be developed.
            return null;
        }

        /// <summary>
        ///   Generate a new Agnis Form 2450 Post-TED form for the annual report, for an EBMT patient passed as parameter.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient ID (center id owning this patient) </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient IDAA </param>
        /// <param name="ebmtDateOfTransplant"> The date of transplant </param>
        /// <param name="agnisFormPublicID"> The Agnis Form Public ID </param>
        /// <param name="agnisFormVersion"> The Agnis Form Version Number </param>
        /// <returns> An AGNIS FormRevision object. </returns>
        public FormRevision GenerateAnnualForm2450(int ebmtPatientID, int ebmtPatientIDAA, DateTime ebmtDateOfTransplant,
                                                   int agnisFormPublicID, decimal agnisFormVersion)
        {
            //TODO: This Form issue needs still to be developed.
            return null;
        }

        #endregion

        #region Form 2900 generation

        /// <summary>
        ///   Generates a 2900 Form for the patient passed as parameter.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient's Center ID </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient's ID on this center. </param>
        /// <param name="ebmtDateOfTransplant"> </param>
        /// <param name="agnisFormPublicID"> The AGNIS form Public ID. </param>
        /// <param name="agnisFormVersion"> The AGNIS form version. </param>
        /// <param name="instanceID"> </param>
        /// <returns> An AGNIS FormRevision object </returns>
        public FormRevision GenerateForm2900(int ebmtPatientID, int ebmtPatientIDAA, DateTime ebmtDateOfTransplant,
                                             int agnisFormPublicID, decimal agnisFormVersion, string instanceID)
        {
            //We load the patient ebmt data.
            patientID = ebmtPatientID;
            patientIDAA = ebmtPatientIDAA;
            dateOfTransplant = ebmtDateOfTransplant;
            dsEbmtPatientG = EbmtDAL.EbmtDAL.LoadPatientData(ebmtPatientID, ebmtPatientIDAA);
            //We initialize the objects used to create different patient data views.
            EbmtDAL.EbmtDAL.InitializePatientDataBindingSourcesG(dsEbmtPatientG);
            //We execute the translation process.
            return TranslateToAgnisForm(agnisFormPublicID, agnisFormVersion, instanceID);
        }

        #endregion

        #region Form 2400 generation

        /// <summary>
        ///   Generates a 2400 AGNIS form for the patient passed as parameter.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient's Center ID </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient's ID on this center. </param>
        /// <param name="ebmtDateOfTransplant"> The date of transplant. </param>
        /// <param name="agnisFormPublicID"> The AGNIS form Public ID. </param>
        /// <param name="agnisFormVersion"> The AGNIS form version. </param>
        /// <param name="instanceId"> Form instance Id </param>
        /// <returns> </returns>
        public FormRevision GenerateForm2400(int ebmtPatientID, int ebmtPatientIDAA, DateTime ebmtDateOfTransplant,
                                             int agnisFormPublicID, decimal agnisFormVersion, string instanceId)
        {
            //We load the patient ebmt data.
            patientID = ebmtPatientID;
            patientIDAA = ebmtPatientIDAA;
            dateOfTransplant = ebmtDateOfTransplant;
            dsEbmtPatientG = EbmtDAL.EbmtDAL.LoadPatientData(ebmtPatientID, ebmtPatientIDAA);
            //We initialize the objects used to create different patient data views.
            EbmtDAL.EbmtDAL.InitializePatientDataBindingSourcesG(dsEbmtPatientG);
            //We execute the translation process.
            return TranslateToAgnisForm(agnisFormPublicID, agnisFormVersion, instanceId);
        }

        #endregion

        #region Form 2804 generation

        /// <summary>
        ///   Generates a 2804 AGNIS form for the patient passed as parameter.
        /// </summary>
        /// <param name="ebmtPatientID"> The EBMT patient's Center ID </param>
        /// <param name="ebmtPatientIDAA"> The EBMT patient's ID on this center. </param>
        /// <param name="ebmtDateOfTransplant"> The date of transplant. </param>
        /// <param name="agnisFormPublicID"> The AGNIS form Public ID. </param>
        /// <param name="agnisFormVersion"> The AGNIS form version. </param>
        /// <param name="instanceId"> Form instance Id </param>
        /// <returns> </returns>
        public FormRevision GenerateForm2804(int ebmtPatientID, int ebmtPatientIDAA, DateTime ebmtDateOfTransplant,
                                             int agnisFormPublicID, decimal agnisFormVersion, string instanceId)
        {
            //We load the patient ebmt data.
            patientID = ebmtPatientID;
            patientIDAA = ebmtPatientIDAA;
            dateOfTransplant = ebmtDateOfTransplant;
            dsEbmtPatientG = EbmtDAL.EbmtDAL.LoadPatientData(ebmtPatientID, ebmtPatientIDAA);
            //We initialize the objects used to create different patient data views.
            EbmtDAL.EbmtDAL.InitializePatientDataBindingSourcesG(dsEbmtPatientG);
            //We execute the translation process.
            return TranslateToAgnisForm(agnisFormPublicID, agnisFormVersion, instanceId);
        }

        #endregion

        #endregion

        #region Translation process methods.

        /// <summary>
        ///   Instanciate an Agnis object, then Generate an XML report file format
        /// </summary>
        /// <param name="formPublicID"> </param>
        /// <param name="formVersion"> </param>
        /// <param name="instanceId"> </param>
        private FormRevision TranslateToAgnisForm(int formPublicID, decimal formVersion, string instanceId)
        {
            //We create the Agnis required objects and we filled them out.
            textReport = "";
            textReport2 = "";
            Form newAgnisForm = MappingInfoDAL.aForm;
            newAgnisForm.publicId = formPublicID;
            newAgnisForm.version = formVersion;
            newAgnisForm.publicIdSpecified = true;
            newAgnisForm.versionSpecified = true;
            newAgnisForm.originator = new Institution();
            newAgnisForm.originator.uniqueName = "cibmtr_center_number:10186";
            newAgnisForm.instanceId = instanceId;

            FormRevision newAgnisFormRevision = MappingInfoDAL.aFormRevision;
            newAgnisFormRevision.form = newAgnisForm;
            //This following list is the list of module INSTANCES in the form.
            //Meaning that the same Module PublicID could be repeated in the range limited by the column "[Module Max Repeat]"
            //wich is the maximum number of instances for a module starting on zero.
            List<Module> modulesCollection = new List<Module>();
            //This dataview is going to give us the list of modules belonging to this form with the information of
            //the number of instances allowed for each module.
            DataView dvModulesList = MappingInfoDAL.GetModulesListForThisForm(dsMappingInfo, formPublicID, formVersion);
            if (dvModulesList != null)
            {
                //RRA  : Si instance_id <> null alors on ajoute le module pUBLIC id, signifiant que c'est un envoi pour mise à jour;      
                if (instanceId != "")
                {
                    List<Module> resultSingleModInstancesList = GetFormInstanceIdModule(instanceId, formPublicID,
                                                                                        formVersion);
                    if (resultSingleModInstancesList.Count > 0)
                    {
                        foreach (Module SingleModuleIns in resultSingleModInstancesList)
                        {
                            modulesCollection.Add(SingleModuleIns);
                        }
                    }
                }
                foreach (DataRowView moduleRowView in dvModulesList)
                {
                    //For each module information in this list we process the module and return a list of modules instances
                    //corresponding to the modules instances generated by this process (in the limits of "[Module Max Repeat]")
                    MappingDataSet.ModulesListRow moduleRow = (MappingDataSet.ModulesListRow) moduleRowView.Row;
                    List<Module> resultModInstancesList = ProcessModule(moduleRow);
                    if (resultModInstancesList.Count > 0)
                    {
                        foreach (Module moduleIns in resultModInstancesList)
                        {
                            modulesCollection.Add(moduleIns);
                        }
                    }
                }

                textReport = textReport + "List of Records Selections ID backed up:" + "\r\n";
                foreach (RecordSelectionMem rItem in EbmtDAL.EbmtDAL.recordsSelectionsList)
                {
                    textReport = textReport + "Record Selection ID: " + rItem.RecordSelectionId + "\r\n";
                }

                newAgnisFormRevision.moduleCollection = modulesCollection.ToArray<Module>();
                string xmlOutput = SerializeObjectToXmlString(newAgnisFormRevision);
                string fileName = Settings.Default.AgnisTranslatedFormOutputDir +
                                  "/patID_ID_patIDAA_IDAA_transplant_tDate_form_PublicID_XXXX_output.xml";
                string rptFileName = Settings.Default.AgnisTranslatedFormOutputDir +
                                     "/patID_ID_patIDAA_IDAA_transplant_tDate_form_PublicID_XXXX_report.txt";
                string rptFileName2 = Settings.Default.AgnisTranslatedFormOutputDir +
                                      "/patID_ID_patIDAA_IDAA_form_PublicID_XXXX_report2.txt";
                fileName = fileName.Replace("_XXXX_", "_" + formPublicID + "_");
                fileName = fileName.Replace("_ID_", "_" + patientID + "_");
                fileName = fileName.Replace("_IDAA_", "_" + patientIDAA + "_");
                fileName = fileName.Replace("_tDate_",
                                            "_" + dateOfTransplant.ToShortDateString().Replace("/", "-") + "_");
                rptFileName = rptFileName.Replace("_XXXX_", "_" + formPublicID + "_");
                rptFileName = rptFileName.Replace("_ID_", "_" + patientID + "_");
                rptFileName = rptFileName.Replace("_IDAA_", "_" + patientIDAA + "_");
                rptFileName = rptFileName.Replace("_tDate_",
                                                  "_" + dateOfTransplant.ToShortDateString().Replace("/", "-") + "_");
                rptFileName2 = rptFileName2.Replace("_XXXX_", "_" + formPublicID + "_");
                rptFileName2 = rptFileName2.Replace("_ID_", "_" + patientID + "_");
                rptFileName2 = rptFileName2.Replace("_IDAA_", "_" + patientIDAA + "_");
                StreamWriter sWriter = new StreamWriter(fileName, false);
                StreamWriter sWriter2 = new StreamWriter(rptFileName, false);
                StreamWriter sWriter3 = new StreamWriter(rptFileName2, false);
                sWriter.Write(xmlOutput);
                sWriter2.Write(textReport);
                sWriter3.Write(textReport2);
                sWriter.Close();
                sWriter2.Close();
                sWriter3.Close();
                return newAgnisFormRevision;
            }
            throw new TranslationException("The function GetFormModulesList has returned an invalid value");
        }

        #region Filling Agnis objects.

        /// <summary>
        ///   Process the module passed as parameter. It calls the AssembleModuleInstances method in order to return a List of module instances for the module.
        /// </summary>
        /// <param name="moduleRow"> </param>
        /// <returns> </returns>
        private List<Module> ProcessModule(MappingDataSet.ModulesListRow moduleRow)
        {
            textReport = textReport +
                         "___________________________________________________________________________________" + "\r\n";
            textReport = textReport + "Processing Module Public ID: " + moduleRow.Module_Public_ID + "\r\n";
            textReport = textReport + "Normalized Module: " + moduleRow.Normalized + "\r\n";
            return AssembleModuleInstances(moduleRow);
        }

        /// <summary>
        ///   This function will get the Module indicating that this is an update submission.The module will contain the Instance ID and the Form Public ID
        /// </summary>
        /// <param name="instance_id"> </param>
        /// <param name="formPublicID"> </param>
        /// <param name="formVersion"> </param>
        /// <returns> </returns>
        private List<Module> GetFormInstanceIdModule(string instance_id, int formPublicID, decimal formVersion)
        {
            DataView dvModule = new DataView(dsMappingInfo.FieldValues);
            dvModule.RowFilter = "[caDSR Form Public ID]='" + formPublicID + "' AND " +
                                 "[caDSR Form Version]='" + formVersion + "' AND " +
                                 "[CDE Public ID]='2527889'";
            if (dvModule.Count > 0)
            {
                int modPubId = int.Parse(dvModule[0]["Module Public ID"].ToString());
                int modVersionId = int.Parse(dvModule[0]["Module Version"].ToString());
                List<Module> moduleIntances = new List<Module>();

                //specific Module for an update submitting
                const int repeatSeqNumber = 1;
                Module nonNorModule = new Module();
                nonNorModule.publicId = modPubId;
                nonNorModule.version = modVersionId;
                nonNorModule.repeatSequenceNumber = repeatSeqNumber.ToString();
                nonNorModule.publicIdSpecified = true;
                nonNorModule.versionSpecified = true;

                //DataView dv_nonNormalizeQuestionsList = MappingInfoDAL.GetQuestionsListForThisModule(dsMappingInfo, moduleRow);
                List<Question> mQuestions = new List<Question>();

                Question aQuestion = new Question();
                aQuestion.dataElementPublicId = long.Parse("2527889");
                aQuestion.dataElementVersion = decimal.Parse("1");
                aQuestion.value = instance_id;
                aQuestion.dataElementPublicIdSpecified = true;
                aQuestion.dataElementVersionSpecified = true;
                mQuestions.Add(aQuestion);

                if (mQuestions.Count > 0)
                {
                    nonNorModule.questionCollection = mQuestions.ToArray<Question>();
                    moduleIntances.Add(nonNorModule);
                }
                return moduleIntances;
            }
            throw new TranslationException("There is no module row for this filter");
        }

        /// <summary>
        ///   Assembles the list of instances for this module. Generates a List of Agnis Module objects.
        /// </summary>
        /// <param name="moduleRow"> </param>
        /// <returns> moduleIntances </returns>
        private List<Module> AssembleModuleInstances(MappingDataSet.ModulesListRow moduleRow)
        {
            List<Module> moduleIntances = new List<Module>();
            int repeatSeqNumber;
            TranslationAnswer posAnswer = new TranslationAnswer();
            posAnswer.hasAResponse = true;
            //***********************************Normalized repeating modules.***************************************************
            if (moduleRow.Normalized == "Yes")
            {
                //We get the list of permissible values for the Mapping CDE of this module.
                DataView dvModuleMappingQuestionValuesList =
                    MappingInfoDAL.GetValuesListForThisMappingQuestion(dsMappingInfo, moduleRow);

                if (dvModuleMappingQuestionValuesList != null)
                {
                    repeatSeqNumber = 0;
                    //Then we iterate between these permissible values.
                    foreach (DataRowView mappingQuestionValueRowView in dvModuleMappingQuestionValuesList)
                    {
                        //We create the module instance that we are going to add to the modules instances list.
                        //This module instance is going to be added to that list only if 
                        //the question belonging to this module is answered.
                        repeatSeqNumber += 1;
                        textReport = textReport + "Repeat sequence number: " + repeatSeqNumber + "\r\n";
                        Module norModule = new Module();
                        norModule.publicId = moduleRow.Module_Public_ID;
                        norModule.version = (decimal) moduleRow.Module_Version;
                        norModule.repeatSequenceNumber = repeatSeqNumber.ToString();
                        norModule.publicIdSpecified = true;
                        norModule.versionSpecified = true;
                        MappingDataSet.NormalizedValuesListRow mappingQValue =
                            (MappingDataSet.NormalizedValuesListRow) mappingQuestionValueRowView.Row;
                        List<Question> mQuestions = new List<Question>();


                        //We fill this module instance with the principal (or mapping) question.
                        Question aQuestion = new Question();
                        aQuestion.dataElementPublicId = mappingQValue.CDE_Public_ID;
                        aQuestion.dataElementVersion = (decimal) mappingQValue.CDE_Version;
                        aQuestion.value = mappingQValue.Valid_Value_Long_Name;
                        aQuestion.dataElementPublicIdSpecified = true;
                        aQuestion.dataElementVersionSpecified = true;
                        mQuestions.Add(aQuestion);
                        textReport = textReport + "*********************************************************" + "\r\n";
                        textReport = textReport + "Mapping Question: " + mappingQValue.CDE_Public_ID + "\r\n";
                        textReport = textReport + "Mapping Question Value Meaning Text: " +
                                     mappingQValue.Value_Meaning_Text + "\r\n";

                        DataView dvModuleQuestionsList =
                            MappingInfoDAL.GetQuestionsListForThisNormalizedModule(dsMappingInfo, mappingQValue);
                        if (dvModuleQuestionsList != null)
                        {
                            foreach (DataRowView questionRowView in dvModuleQuestionsList)
                            {
                                if (moduleRow.Module_Public_ID == 3045099)
                                {
                                }
                                MappingDataSet.MappingQValueQuestionsListRow qValueQuestionRow =
                                    (MappingDataSet.MappingQValueQuestionsListRow) questionRowView.Row;
                                DataView dv_ValuesList =
                                    MappingInfoDAL.GetPermissibleValuesForThisNormalizedQuestion(dsMappingInfo,
                                                                                                 qValueQuestionRow,
                                                                                                 moduleRow);
                                if (dv_ValuesList != null)
                                {
                                    foreach (DataRowView rv_Value in dv_ValuesList)
                                    {
                                        MappingDataSet.NormalizedValuesListRow norValueRow =
                                            (MappingDataSet.NormalizedValuesListRow) rv_Value.Row;
                                        TranslationAnswer myAnswer =
                                            GetAnswerForThisNormalizedQuestionValueCombination(qValueQuestionRow,
                                                                                               norValueRow);
                                        textReport = textReport + "********Sub Question: " + norValueRow.CDE_Public_ID +
                                                     "\r\n";
                                        textReport = textReport + "Value Meaning Public ID: " +
                                                     norValueRow["Value Meaning Public ID"] + "\r\n";
                                        textReport = textReport + "Value Meaning Text: " +
                                                     norValueRow["Value Meaning Text"] + "\r\n";
                                        textReport = textReport + "Valid Value Long Name: " +
                                                     norValueRow["Valid Value Long Name"] + "\r\n";
                                        textReport = textReport + "Has a Response: " + myAnswer.hasAResponse + "\r\n";


                                        if (myAnswer.hasAResponse == posAnswer.hasAResponse)
                                        {
                                            //If this value was satisfied we fill the question.
                                            Question aQuestion2 = new Question();
                                            aQuestion2.dataElementPublicId = norValueRow.CDE_Public_ID;
                                            aQuestion2.dataElementVersion = (decimal) norValueRow.CDE_Version;
                                            aQuestion2.value = myAnswer.freeTextEntry ? myAnswer.textAnswer : norValueRow.Valid_Value_Long_Name;
                                            if (aQuestion2.value == "NA")
                                            {
                                                aQuestion2.value = "";
                                                aQuestion2.errorException = "UA";
                                            }
                                            aQuestion2.dataElementPublicIdSpecified = true;
                                            aQuestion2.dataElementVersionSpecified = true;
                                            mQuestions.Add(aQuestion2);
                                            textReport = textReport + "Response value: " + aQuestion2.value + "\r\n";
                                        }
                                    }
                                }
                            }
                        }
                        if (mQuestions.Count > 1)
                        {
                            norModule.questionCollection = mQuestions.ToArray<Question>();
                            moduleIntances.Add(norModule);
                        }
                    }
                }
            }
                //***********************************Non-normalized modules***************************************
            else
            {
                //Non-normalized non-repeating modules
                if (moduleRow.Module_Max_Repeat == 0)
                {
                    //We create the UNIQUE module instance that we are going to add to the modules list just if the question
                    //belonging to this module is answered.
                    repeatSeqNumber = 1;
                    textReport = textReport + "Repeat sequence number: " + repeatSeqNumber + "\r\n";
                    Module nonNorModule = new Module();
                    nonNorModule.publicId = moduleRow.Module_Public_ID;
                    nonNorModule.version = (decimal) moduleRow.Module_Version;
                    nonNorModule.repeatSequenceNumber = repeatSeqNumber.ToString();
                    nonNorModule.publicIdSpecified = true;
                    nonNorModule.versionSpecified = true;

                    DataView dv_nonNormalizeQuestionsList = MappingInfoDAL.GetQuestionsListForThisModule(dsMappingInfo,
                                                                                                         moduleRow);
                    List<Question> mQuestions = new List<Question>();

                    if (dv_nonNormalizeQuestionsList.Count > 0)
                    {
                        //foreach row in my list
                        foreach (DataRowView dv_nonNormalizeQuestionRow in dv_nonNormalizeQuestionsList)
                        {
                            DataRow nonNQuestionRow = dv_nonNormalizeQuestionRow.Row;
                            DataView dv_ValuesList =
                                MappingInfoDAL.GetPermissibleValuesForThisNonNormalizedQuestion(dsMappingInfo,
                                                                                                nonNQuestionRow,
                                                                                                moduleRow);

                            if (nonNQuestionRow["CDE Public ID"].ToString() == "2494565")
                            {
                            }

                            textReport = textReport + "*********************************************************" +
                                         "\r\n";
                            textReport = textReport + "Question: " + nonNQuestionRow["CDE Public ID"] + "\r\n";
                            textReport = textReport + "Question Long Name: " + nonNQuestionRow["Question Long Name"] +
                                         "\r\n";

                            foreach (DataRowView rv_Value in dv_ValuesList)
                            {
                                DataRow nonNorValueRow = rv_Value.Row;

                                TranslationAnswer myAnswer = GetAnswerForThisNonNormalizedQuestionValueCombination(nonNQuestionRow,
                                                                                                                   nonNorValueRow,
                                                                                                                   moduleRow.
                                                                                                                       Module_Max_Repeat);

                                textReport = textReport + "Value Meaning Public ID: " +
                                             nonNorValueRow["Value Meaning Public ID"] + "\r\n";
                                textReport = textReport + "Value Meaning Text: " + nonNorValueRow["Value Meaning Text"] +
                                             "\r\n";
                                textReport = textReport + "Valid Value Long Name: " +
                                             nonNorValueRow["Valid Value Long Name"] + "\r\n";
                                textReport = textReport + "Has a Response: " + myAnswer.hasAResponse + "\r\n";

                                if (myAnswer.hasAResponse == posAnswer.hasAResponse)
                                {
                                    //If this value was satisfied we fill the question.
                                    Question aQuestion = new Question();
                                    aQuestion.dataElementPublicId =
                                        long.Parse(nonNorValueRow["CDE Public ID"].ToString());
                                    aQuestion.dataElementVersion =
                                        decimal.Parse(nonNorValueRow["CDE Version"].ToString());
                                    if (myAnswer.freeTextEntry)
                                    {
                                        aQuestion.value = myAnswer.textAnswer;
                                    }
                                    else
                                    {
//rg 2012-04-12- deals with the empty descriptions
                                        if (nonNorValueRow["Valid Value Long Name"].ToString().Length > 0)
                                        {
                                            aQuestion.value = (String) nonNorValueRow["Valid Value Long Name"];
                                        }
                                        else
                                        {
                                            aQuestion.value = "";
                                        }
                                    }
                                    setExceptionErrorValueCode(aQuestion);

                                    aQuestion.dataElementPublicIdSpecified = true;
                                    aQuestion.dataElementVersionSpecified = true;
                                    mQuestions.Add(aQuestion);
                                    textReport = textReport + "Response value: " + aQuestion.value + "\r\n";
                                    break;
                                }
                            }
                        }
                    }
                    if (mQuestions.Count > 0)
                    {
                        nonNorModule.questionCollection = mQuestions.ToArray<Question>();
                        moduleIntances.Add(nonNorModule);
                    }
                }

                    //Non-normalized repeating modules
                else if (moduleRow.Module_Max_Repeat > 0)
                {
                    List<Question> valueMeaningIDsAnswers = new List<Question>();
                    List<BackupValueAnswer> valueAnswers = new List<BackupValueAnswer>();
                    for (int i = 1; i <= moduleRow.Module_Max_Repeat + 1; i++)
                    {
                        repeatSeqNumber = i;
                        textReport = textReport + "Repeat sequence number: " + repeatSeqNumber + "\r\n";
                        Module nonNorModule = new Module();
                        nonNorModule.publicId = moduleRow.Module_Public_ID;
                        nonNorModule.version = (decimal) moduleRow.Module_Version;
                        nonNorModule.repeatSequenceNumber = repeatSeqNumber.ToString();
                        nonNorModule.publicIdSpecified = true;
                        nonNorModule.versionSpecified = true;

                        DataView dv_nonNormalizeQuestionsList =
                            MappingInfoDAL.GetQuestionsListForThisModule(dsMappingInfo, moduleRow);
                        List<Question> mQuestions = new List<Question>();
                        if (dv_nonNormalizeQuestionsList.Count > 0)
                        {
                            foreach (DataRowView dv_nonNormalizeQuestionRow in dv_nonNormalizeQuestionsList)
                            {
                                DataRow nonNQestionRow = dv_nonNormalizeQuestionRow.Row;
                                DataView dv_ValuesList =
                                    MappingInfoDAL.GetPermissibleValuesForThisNonNormalizedQuestion(dsMappingInfo,
                                                                                                    nonNQestionRow,
                                                                                                    moduleRow);
                                textReport = textReport + "*********************************************************" +
                                             "\r\n";
                                textReport = textReport + "Question: " + nonNQestionRow["CDE Public ID"] + "\r\n";
                                textReport = textReport + "Question Long Name: " + nonNQestionRow["Question Long Name"] +
                                             "\r\n";


                                if (dv_ValuesList != null)
                                {
                                    foreach (DataRowView rv_Value in dv_ValuesList)
                                    {
                                        DataRow nonNorValueRow = rv_Value.Row;
                                        TranslationAnswer myAnswer = null;
                                        bool valueAlreadyTested = false;
                                        //************** Section to verify if we have already tested a value**********************
                                        foreach (BackupValueAnswer tAnswer in valueAnswers)
                                        {
                                            if (tAnswer.value == nonNorValueRow["Valid Value Long Name"].ToString() &&
                                                tAnswer.cdePid == nonNorValueRow["CDE Public ID"].ToString())
                                            {
                                                //If the value alread exist into the backup list of tested values
                                                //We copy the answer.
                                                myAnswer = new TranslationAnswer();
                                                myAnswer.hasAResponse = tAnswer.hasResponse;
                                                myAnswer.freeTextEntry = tAnswer.freeTextEntry;
                                                valueAlreadyTested = true;
                                                break;
                                            }
                                        }
                                        if (nonNorValueRow["Value Meaning Public ID"].ToString() == "2684928")
                                        {
                                        }
                                        if (!valueAlreadyTested)
                                        {
                                            //If the value was not already tested we start the test as normally.
                                            myAnswer =
                                                GetAnswerForThisNonNormalizedQuestionValueCombination(nonNQestionRow,
                                                                                                      nonNorValueRow, i);
                                            //We add the new answer to the backup list of tested values.
                                            valueAnswers.Add(
                                                new BackupValueAnswer(nonNorValueRow["CDE Public ID"].ToString(),
                                                                      nonNorValueRow["Valid Value Long Name"].ToString(),
                                                                      myAnswer.hasAResponse, myAnswer.freeTextEntry));
                                        }
                                        //****************************************************************************************
                                        textReport = textReport + "Value Meaning Public ID: " +
                                                     nonNorValueRow["Value Meaning Public ID"] + "\r\n";
                                        textReport = textReport + "Value Meaning Text: " +
                                                     nonNorValueRow["Value Meaning Text"] + "\r\n";
                                        textReport = textReport + "Valid Value Long Name: " +
                                                     nonNorValueRow["Valid Value Long Name"] + "\r\n";
                                        textReport = textReport + "Has a Response: " + myAnswer.hasAResponse + "\r\n";

                                        if (myAnswer.hasAResponse)
                                        {
                                            //If this value was satisfied we fill the question.
                                            Question aQuestion = new Question();
                                            aQuestion.dataElementPublicId =
                                                long.Parse(nonNorValueRow["CDE Public ID"].ToString());
                                            aQuestion.dataElementVersion =
                                                decimal.Parse(nonNorValueRow["CDE Version"].ToString());

                                            if (myAnswer.freeTextEntry)
                                            {
                                                aQuestion.value = myAnswer.textAnswer;
                                            }
                                            else
                                            {
                                                aQuestion.value = (String) nonNorValueRow["Valid Value Long Name"];
                                            }
                                            setExceptionErrorValueCode(aQuestion);
                                            bool valueAlreadyExist = false;
                                            foreach (Question tAnswer in valueMeaningIDsAnswers)
                                            {
                                                if (tAnswer.value == aQuestion.value &&
                                                    tAnswer.dataElementPublicId == aQuestion.dataElementPublicId)
                                                {
                                                    valueAlreadyExist = true;
                                                    break;
                                                }
                                            }

                                            if (!valueAlreadyExist)
                                            {
                                                if (aQuestion.value != null)
                                                {
                                                    aQuestion.dataElementPublicIdSpecified = true;
                                                    aQuestion.dataElementVersionSpecified = true;
                                                    mQuestions.Add(aQuestion);
                                                    valueMeaningIDsAnswers.Add(aQuestion);
                                                }
                                                break;
                                            }

                                            textReport = textReport + "Response value: " + aQuestion.value + "\r\n";
                                        }
                                    }
                                }
                            }
                        }
                        //if (mQuestions.Count == dv_nonNormalizeQuestionsList.Count)
                        if (mQuestions.Count > 0)
                        {
                            nonNorModule.questionCollection = mQuestions.ToArray<Question>();
                            moduleIntances.Add(nonNorModule);
                        }
                    }
                }
            }
            //***************************************************************************************************
            return moduleIntances;
        }

        /// <summary>
        ///   RRA - 02/27/2012 Override code NA = not mapped fields UA = no data filled
        /// </summary>
        /// <param name="aQuestion"> </param>
        private void setExceptionErrorValueCode(Question aQuestion)
        {
            switch (aQuestion.value)
            {
                case "NA":
                    aQuestion.value = "";
                    aQuestion.errorException = "NA";
                    break;
                case "UA":
                    aQuestion.value = "";
                    aQuestion.errorException = "UA";
                    break;
            }
        }

        private class BackupValueAnswer
        {
            public readonly String cdePid;
            public readonly bool freeTextEntry;
            public readonly bool hasResponse;
            public readonly String value;

            public BackupValueAnswer(String cdePublicId, String val, bool resp, bool isTextEntry)
            {
                cdePid = cdePublicId;
                value = val;
                hasResponse = resp;
                freeTextEntry = isTextEntry;
            }
        }

        #endregion

        #region Translation logic

        /// <summary>
        ///   Gets the datarow for this normalized question-value combination.
        /// </summary>
        /// <param name="qValueQuestion"> </param>
        /// <param name="valueRow"> </param>
        /// <returns> A FieldValuesRow object. </returns>
        public MappingDataSet.FieldValuesRow GetRowForThisNormalizedQuestionValueCombination(
            MappingDataSet.MappingQValueQuestionsListRow qValueQuestion, MappingDataSet.NormalizedValuesListRow valueRow)
        {
            DataView myVariableView = new DataView(dsMappingInfo.FieldValues);
            if (valueRow["Value Meaning Public ID"] != DBNull.Value)
            {
                myVariableView.RowFilter = "[Module Public ID]='" + qValueQuestion.Module_Public_ID + "' AND "
                                           + "[Module Version]='" + qValueQuestion.Module_Version + "' AND "
                                           + "[Value Meaning Public ID]='" + qValueQuestion.Value_Meaning_Public_ID +
                                           "' AND "
                                           + "[Value Meaning Version]='" + qValueQuestion.Value_Meaning_Version +
                                           "' AND "
                                           + "[CDE Public ID 2]='" + valueRow.CDE_Public_ID + "' AND "
                                           + "[CDE Version 2]='" + valueRow.CDE_Version + "' AND "
                                           + "[Value Meaning Public ID 2]='" + valueRow.Value_Meaning_Public_ID +
                                           "' AND "
                                           + "[Value Meaning Version 2]='" + valueRow.Value_Meaning_Version + "'";
            }
            else
            {
                myVariableView.RowFilter = "[Module Public ID]='" + qValueQuestion.Module_Public_ID + "' AND "
                                           + "[Module Version]='" + qValueQuestion.Module_Version + "' AND "
                                           + "[Value Meaning Public ID]='" + qValueQuestion.Value_Meaning_Public_ID +
                                           "' AND "
                                           + "[Value Meaning Version]='" + qValueQuestion.Value_Meaning_Version +
                                           "' AND "
                                           + "[CDE Public ID 2]='" + valueRow.CDE_Public_ID + "' AND "
                                           + "[CDE Version 2]='" + valueRow.CDE_Version + "'";
            }
            if (myVariableView.Count > 0)
            {
                MappingDataSet.FieldValuesRow varRow = (MappingDataSet.FieldValuesRow) myVariableView[0].Row;
                return varRow;
            }
            throw new TranslationException("The program didn't find any rows while filtering the Variables table.");
        }

        /// <summary>
        ///   Gets the datarow for this non-normalized question-value combination.
        /// </summary>
        /// <param name="questionValueRow"> </param>
        /// <param name="valueRow"> </param>
        /// <returns> A FieldValuesRow object. </returns>
        public MappingDataSet.FieldValuesRow GetRowForThisNonNormalizedQuestionValueCombination(
            DataRow questionValueRow, DataRow valueRow)
        {
            DataView myVariableView = new DataView(dsMappingInfo.FieldValues);
            if (valueRow["Value Meaning Public ID"] != DBNull.Value)
            {
                myVariableView.RowFilter = "[Module Public ID]='" + questionValueRow["Module Public ID"] + "' AND "
                                           + "[Module Version]='" + questionValueRow["Module Version"] + "' AND "
                                           + "[CDE Public ID]='" + questionValueRow["CDE Public ID"] + "' AND "
                                           + "[CDE Version]='" + questionValueRow["CDE Version"] + "' AND "
                                           + "[Value Meaning Public ID]='" + valueRow["Value Meaning Public ID"] +
                                           "' AND "
                                           + "[Value Meaning Version]='" + valueRow["Value Meaning Version"] + "'";
            }
            else
            {
                myVariableView.RowFilter = "[Module Public ID]='" + questionValueRow["Module Public ID"] + "' AND "
                                           + "[Module Version]='" + questionValueRow["Module Version"] + "' AND "
                                           + "[CDE Public ID]='" + questionValueRow["CDE Public ID"] + "' AND "
                                           + "[CDE Version]='" + questionValueRow["CDE Version"] + "'";
            }
            if (myVariableView.Count == 1)
            {
                MappingDataSet.FieldValuesRow varRow = (MappingDataSet.FieldValuesRow) myVariableView[0].Row;
                return varRow;
            }
            throw new TranslationException(
                "The program didn't find a unique row or any rows while filtering the Variables table.");
        }

        /// <summary>
        ///   Does the record selection process.
        /// </summary>
        /// <param name="varRow"> </param>
        /// <param name="isPreSelection"> </param>
        /// <param name="repeatingSequenceNumber"> </param>
        /// <returns> Returns a filtered dataset after applying all the record selection filters. </returns>
        public DataSet DoRecordsSelection(MappingDataSet.FieldValuesRow varRow, bool isPreSelection,
                                          int repeatingSequenceNumber)
        {
            if (String.Compare(varRow.HasSelection, "Yes", StringComparison.OrdinalIgnoreCase) == 0 ||
                (String.Compare(varRow.HasSelection, "Yes", StringComparison.OrdinalIgnoreCase) == 0 && isPreSelection))
            {
                String recordsSelectionGroupID;
                if (isPreSelection)
                {
                    if (varRow.EBMT_PreSelection_ID == "" || varRow["EBMT PreSelection ID"] == DBNull.Value)
                    {
                    }
                    recordsSelectionGroupID = varRow.EBMT_PreSelection_ID;
                }
                else
                {
                    try
                    {
                        recordsSelectionGroupID = varRow.EBMT_Records_Selection_ID;
                    }
                    catch
                    {
                        throw new Exception();
                    }
                }
                if (recordsSelectionGroupID == "GS2450-2-076")
                {
                }
                //*********************We apply the records selection.************************************
                //We instantiate a temporary empty dataset to fill with the resulting rows of our record selection process.
                DataSet dsTemp = new DataSet();
                BindingSource bsRecordsSelectionGroups = new BindingSource();
                bsRecordsSelectionGroups.DataSource = dsMappingInfo;
                bsRecordsSelectionGroups.DataMember = dsMappingInfo.RecordsSelectionGroups.TableName;
                bsRecordsSelectionGroups.Filter = "[EBMT Selections Group ID]='" + recordsSelectionGroupID + "'";

                if (bsRecordsSelectionGroups.Count > 0)
                {
                    //For each record selection item in the record selection group
                    //we apply the filters and return the datarows.
                    foreach (DataRowView drView in bsRecordsSelectionGroups.List)
                    {
                        MappingDataSet.RecordsSelectionGroupsRow drRecordsSelectionGroup =
                            (MappingDataSet.RecordsSelectionGroupsRow) drView.Row;
                        dsTemp.Merge(EbmtDAL.EbmtDAL.ApplyRecordsSelectionG2(dsMappingInfo,
                                                                             drRecordsSelectionGroup.EBMT_Selections_ID,
                                                                             repeatingSequenceNumber, dateOfTransplant));
                    }
                }
                return dsTemp;
            }
            //*******************We return an unfiltered EBMT dataset object.***************************
            return EbmtDAL.EbmtDAL.GetNonFilteredEBMTDataSetG2();
        }

        /// <summary>
        ///   Does the pre-conditions process if there is any.
        /// </summary>
        /// <param name="varRow"> </param>
        /// <param name="valueRow"> </param>
        /// <param name="repeatingSequenceNumber"> </param>
        /// <returns> True if the precondition process was tested succesfull, false if not. </returns>
        public Boolean DoPreConditions(MappingDataSet.FieldValuesRow varRow, DataRow valueRow,
                                       int repeatingSequenceNumber)
        {
            if (varRow["HasPreConditions"] != DBNull.Value)
            {
                if (String.Compare(varRow.HasPreConditions, "Yes", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    //We apply the records pre-selection for this mapping definition.
                    dsFilteredEbmtPatientG = DoRecordsSelection(varRow, true, repeatingSequenceNumber);

                    //We use a TranslationAnswer object to retrieve the PreCondition test result.
                    TranslationAnswer preAnswer = DoMappingConditions(varRow, true, valueRow);

                    if (preAnswer.hasAResponse)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }
            return true;
        }

        /// <summary>
        ///   Does the MappingConditions process. Process each ConditionId from the list of conditions in the group.
        /// </summary>
        /// <param name="varRow"> </param>
        /// <param name="isPreCondition"> </param>
        /// <param name="valueRow"> </param>
        /// <returns> A TranslationAnswer object containing the result of testing the conditions process. </returns>
        public TranslationAnswer DoMappingConditions(MappingDataSet.FieldValuesRow varRow, bool isPreCondition,
                                                     DataRow valueRow)
        {
            TranslationAnswer myAnswer = new TranslationAnswer();
            BindingSource bsMappingConditionsGroups = new BindingSource();
            bsMappingConditionsGroups.DataSource = dsMappingInfo;
            bsMappingConditionsGroups.DataMember = "MappingConditionsGroups";
            String mappingConditionGroupID;
            if (isPreCondition)
            {
                mappingConditionGroupID = varRow.EBMT_PreConditions_ID;
                textReport2 = textReport2 + "Pre Conditions Group Id:" + varRow.EBMT_PreConditions_ID + "\r\n";
            }
            else
            {
                mappingConditionGroupID = varRow.EBMT_Conditions_ID;
                textReport2 = textReport2 + "Conditions Group Id:" + varRow.EBMT_Conditions_ID + "\r\n";
            }
            bsMappingConditionsGroups.Filter = "[EBMT Conditions Group ID]='" + mappingConditionGroupID + "'";

            //if (mappingConditionGroupID == "GC2400-1-041")
            if (mappingConditionGroupID == "GC2400-3-073")
            {
            }


            if (bsMappingConditionsGroups.Count > 0)
            {
                bool RelationResultAnd = true;
                bool RelationResultOr = false;

                foreach (DataRowView drView in bsMappingConditionsGroups.List)
                {
                    TranslationAnswer tempAnswer;

                    MappingDataSet.MappingConditionsGroupsRow drConditions =
                        (MappingDataSet.MappingConditionsGroupsRow) drView.Row;
                    if (drConditions["RelationshipOperator"] != DBNull.Value)
                    {
                        if (String.Compare(drConditions.RelationshipOperator, "OR", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            RelationResultAnd = false;
                            tempAnswer = ProcessConditionId(drConditions, varRow, valueRow);
                            RelationResultOr = RelationResultOr || tempAnswer.hasAResponse;
                            if (tempAnswer.hasAResponse)
                            {
                                myAnswer = tempAnswer;
                            }
                        }
                        else
                        {
                            tempAnswer = ProcessConditionId(drConditions, varRow, valueRow);
                            RelationResultAnd = RelationResultAnd && tempAnswer.hasAResponse;
                            myAnswer = tempAnswer;
                        }
                    }
                    else
                    {
                        tempAnswer = ProcessConditionId(drConditions, varRow, valueRow);
                        RelationResultAnd = RelationResultAnd && tempAnswer.hasAResponse;
                        myAnswer = tempAnswer;
                    }
                }
                if (RelationResultAnd || RelationResultOr)
                {
                    return myAnswer;
                }
                myAnswer.hasAResponse = false;
                return myAnswer;
            }
            throw new TranslationException("There is no condition using this ID.");
        }

        /// <summary>
        ///   Process this Condition Id using the Conditions instructions. Depending on the Instruction this method calls the GetResultOfTestingConditionIdExpressions method: When "All must be true" is specified: it calls this method for each datarow on the filtered dataset unless it finds a false value. When "Stop at last true value" is specified, it calls this method for each datarow on the filtered dataset and returns the last true value if there was any. When any other instruction or when there is not instruction: it calls the same method for each datarow until finding a true value.
        /// </summary>
        /// <param name="drConditions"> </param>
        /// <param name="varRow"> </param>
        /// <param name="valueRow"> </param>
        /// <returns> A TranslationAnswer object containing the result of the test. </returns>
        public TranslationAnswer ProcessConditionId(MappingDataSet.MappingConditionsGroupsRow drConditions,
                                                    MappingDataSet.FieldValuesRow varRow, DataRow valueRow)
        {
            textReport2 = textReport2 + "Processing Condition ID:" + drConditions.EBMT_Conditions_ID + "\r\n";
            TranslationAnswer myAnswer = new TranslationAnswer(drConditions.EBMT_Conditions_ID);
            if (drConditions["Conditions Instruction"] != DBNull.Value)
            {
                //Conditions Instructions are only specified for RecordSelections returning multiple rows.
                //When recordsSelection return multiple rows it can be from only one table.
                if (String.Compare(drConditions.Conditions_Instruction, "All must be true", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (dsFilteredEbmtPatientG.Tables.Contains(drConditions.EBMT_ConTable_ID))
                    {
                        myAnswer.hasAResponse = true;
                        foreach (DataRow dRow in dsFilteredEbmtPatientG.Tables[drConditions.EBMT_ConTable_ID].Rows)
                        {
                            DataSet ebmtResultDataSet = new DataSet();
                            DataRow[] dRows = new DataRow[1];
                            dRows[0] = dRow;
                            ebmtResultDataSet.Merge(dRows);
                            TranslationAnswer tempAnswer = GetResultOfTestingConditionIdExpressions(drConditions.EBMT_Conditions_ID,
                                                                                                    valueRow, varRow, ebmtResultDataSet);
                            tempAnswer.ConditionId = drConditions.EBMT_Conditions_ID;
                            myAnswer.hasAResponse = myAnswer.hasAResponse && tempAnswer.hasAResponse;
                            myAnswer.freeTextEntry = tempAnswer.freeTextEntry;
                            myAnswer.textAnswer = tempAnswer.textAnswer;
                            myAnswer.valueMeaningPublicId = tempAnswer.valueMeaningPublicId;
                        }
                        //if (myAnswer.hasAResponse)
                        //{
                        //    //myAnswer.normalized = true;  RRA le 28/07                                
                        //    myAnswer.textAnswer = tempAnswer.textAnswer;
                        //    myAnswer.valueMeaningPublicId = tempAnswer.valueMeaningPublicId;
                        //}
                        //else
                        //{
                        //    //myAnswer.normalized = false; RRA le 28/07
                        //    return myAnswer;
                        //}
                    }
                    textReport2 = textReport2 + "   Answer:" + myAnswer.hasAResponse + "\r\n";
                    return myAnswer;
                }
                if (String.Compare(drConditions.Conditions_Instruction, "Stop at last true value", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (dsFilteredEbmtPatientG.Tables.Contains(drConditions.EBMT_ConTable_ID))
                    {
                        foreach (DataRow dRow in dsFilteredEbmtPatientG.Tables[drConditions.EBMT_ConTable_ID].Rows)
                        {
                            DataSet ebmtResultDataSet = new DataSet();
                            DataRow[] dRows = new DataRow[1];
                            dRows[0] = dRow;
                            ebmtResultDataSet.Merge(dRows);
                            TranslationAnswer tempAnswer = GetResultOfTestingConditionIdExpressions(drConditions.EBMT_Conditions_ID,
                                                                                                    valueRow, varRow, ebmtResultDataSet);
                            tempAnswer.ConditionId = drConditions.EBMT_Conditions_ID;
                            if (tempAnswer.hasAResponse)
                            {
                                myAnswer.hasAResponse = tempAnswer.hasAResponse;
                                //myAnswer.normalized = true;  RRA le 28/07
                                myAnswer.textAnswer = tempAnswer.textAnswer;
                                myAnswer.valueMeaningPublicId = tempAnswer.valueMeaningPublicId;
                            }
                        }
                    }
                    textReport2 = textReport2 + "   Answer:" + myAnswer.hasAResponse + "\r\n";
                    return myAnswer;
                }
                //"Stop at first true value"
                if (dsFilteredEbmtPatientG.Tables.Contains(drConditions.EBMT_ConTable_ID))
                {
                    foreach (DataRow dRow in dsFilteredEbmtPatientG.Tables[drConditions.EBMT_ConTable_ID].Rows)
                    {
                        DataSet ebmtResultDataSet = new DataSet();
                        DataRow[] dRows = new DataRow[1];
                        dRows[0] = dRow;
                        ebmtResultDataSet.Merge(dRows);
                        TranslationAnswer tempAnswer = GetResultOfTestingConditionIdExpressions(drConditions.EBMT_Conditions_ID,
                                                                                                valueRow, varRow, ebmtResultDataSet);
                        tempAnswer.ConditionId = drConditions.EBMT_Conditions_ID;
                        if (tempAnswer.hasAResponse)
                        {
                            return tempAnswer;
                        }
                    }
                }
                textReport2 = textReport2 + "   Answer:" + myAnswer.hasAResponse + "\r\n";
                return myAnswer;
            }
            if (String.Compare(varRow.HasSelection, "Yes", StringComparison.OrdinalIgnoreCase) == 0)
            {
                //We make sure that the table(s) in the dataset contains only one row.
                //If not we throw an Exception.
                if (dsFilteredEbmtPatientG.Tables.Count > 1)
                {
                    foreach (DataTable t in dsFilteredEbmtPatientG.Tables)
                    {
                        if (t.Rows.Count != 1)
                        {
                            throw new TranslationException(
                                "Multiples rows have been selected and no Conditions Instruction was given.");
                        }
                    }
                }
            }
            myAnswer = GetResultOfTestingConditionIdExpressions(drConditions.EBMT_Conditions_ID, valueRow, varRow,
                                                                dsFilteredEbmtPatientG);
            myAnswer.ConditionId = drConditions.EBMT_Conditions_ID;
            textReport2 = textReport2 + "   Answer:" + myAnswer.hasAResponse + "\r\n";
            return myAnswer;
        }

        public TranslationAnswer GetAnswerForThisQuestionValueCombination(MappingDataSet.FieldValuesRow varRow,
                                                                          DataRow valueRow, int repeatingSequenceNumber)
        {
            // We prepare the TranslationAnswer object that we are going to send.
            TranslationAnswer myAnswer = new TranslationAnswer();
            //We process this answer only if there is a correspondence into the EBMT database.          
            if (String.Compare(varRow.Correspondence_in_EBMT, "Yes", StringComparison.OrdinalIgnoreCase) == 0)
            {
                if (varRow["IsRequired"].ToString() == "Yes")
                {
                }
                //Reset all filters binded to our EBMT original dataset.
                EbmtDAL.EbmtDAL.ResetBindingSourcesRowFiltersG();
                //If the temporary EBMT filtered dataset already exist, we clear any data.
                if (dsFilteredEbmtPatientG != null) dsFilteredEbmtPatientG.Clear();
                //*****If there is a preConditions step we process the PreConditions.***************************
                if (DoPreConditions(varRow, valueRow, repeatingSequenceNumber) == false)
                {
                    //If the preCondition test was negative
                    //we stops the process and return the empty TranslationAnswer object.
                    textReport2 = textReport2 + "Preconditions return false." + "\r\n";
                    //myAnswer is False then we return myAnswer.
                    return myAnswer;
                }
                //If the preCondition test is positive we let the program to continue processing
                //this Field-Value combination.
                //Reset all filters binded to our EBMT original dataset.
                EbmtDAL.EbmtDAL.ResetBindingSourcesRowFiltersG();
                //If the temporary EBMT filtered dataset already exist, we clear any data.
                if (dsFilteredEbmtPatientG != null) dsFilteredEbmtPatientG.Clear();
                //*****Do the Records Selection process.*******************************************************
                dsFilteredEbmtPatientG = DoRecordsSelection(varRow, false, repeatingSequenceNumber);
                //*****Truly named Mapping process***************************************************************
                if (String.Compare(varRow.HasConditions, "Yes", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    TranslationAnswer tempAnswer = DoMappingConditions(varRow, false, valueRow);
                    //Erased with D.Pacheco in order to fix the problem concerning the DOSEs for the drugs.

                    #region

                    //if (varRow["CopyEBMTValue"] != System.DBNull.Value)
                    //{
                    //    if (varRow.CopyEBMTValue == "Yes")
                    //    {
                    //        if (tempAnswer.hasAResponse)
                    //        { return CopyEbmtValue(varRow, dsFilteredEbmtPatientG); }
                    //        else
                    //        { return new TranslationAnswer(); }
                    //    }
                    //    else
                    //    {
                    //        return tempAnswer;
                    //    }
                    //}
                    //else 
                    //{
                    //    return tempAnswer;
                    //}

                    #endregion

                    return tempAnswer;
                }
                if (varRow["CopyEBMTValue"] != DBNull.Value)
                {
                    if (String.Compare(varRow.CopyEBMTValue, "Yes", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        //If there is no conditions to accomplish and we need to copy the real string value from the database.
                        //We just need to verify if there is already some text data in order to send if not we do nothing.
                        //If there is a value send true
                        return CopyEbmtValue(varRow, dsFilteredEbmtPatientG);
                    }
                    throw new TranslationException("HasConditions is 'No' and CopyEBMTValue is different of 'Yes'."
                                                   +
                                                   "\r\nPlease verify: when HasConditions is 'No' or NULL, CopyEBMTValue must be 'Yes'.");
                }
                throw new TranslationException("HasConditions is different of 'Yes' and CopyEBMTValue is NULL."
                                               +
                                               "Please verify: when HasConditions is 'No' or NULL, CopyEBMTValue must be 'Yes'.");
            }
            myAnswer.hasAResponse = false;
            return myAnswer;
        }

        /// <summary>
        ///   If the EBMT database has a value matching exactly this QuestionValue combination, the TranslationAnswer object will have its property hasAResponse as true. If the EBMT database hasn't a value matching this QuestionValue combination, the TranslationAnswer object will have its property hasAResponse as false.
        /// </summary>
        /// <param name="qValueQuestion"> </param>
        /// <param name="valueRow"> </param>
        /// <returns> </returns>
        public TranslationAnswer GetAnswerForThisNormalizedQuestionValueCombination(
            MappingDataSet.MappingQValueQuestionsListRow qValueQuestion,
            MappingDataSet.NormalizedValuesListRow valueRow)
        {
            //We get the row corresponding to this field-value cmbination.
            MappingDataSet.FieldValuesRow varRow = GetRowForThisNormalizedQuestionValueCombination(qValueQuestion,
                                                                                                   valueRow);
            if (varRow["IsRequired"].ToString() == "Yes")
            {
            }
            if (varRow["IsMappingException"] == DBNull.Value)
            {
                return GetAnswerForThisQuestionValueCombination(varRow, valueRow, 0);
            }
            if (String.Compare(varRow.IsMappingException, "Yes", StringComparison.OrdinalIgnoreCase) == 0)
            {
                return GetMappingExceptionValue(varRow);
            }
            return GetAnswerForThisQuestionValueCombination(varRow, valueRow, 0);
        }

        public TranslationAnswer GetAnswerForThisNonNormalizedQuestionValueCombination(DataRow questionValueRow,
                                                                                       DataRow valueRow,
                                                                                       int repeatingSequenceNumber)
        {
            //We get the FieldValue row for this question value combination.
            MappingDataSet.FieldValuesRow varRow = GetRowForThisNonNormalizedQuestionValueCombination(questionValueRow,
                                                                                                      valueRow);

            if (varRow["IsMappingException"] == DBNull.Value)
            {
                return GetAnswerForThisQuestionValueCombination(varRow, valueRow, repeatingSequenceNumber);
            }
            if (String.Compare(varRow["IsMappingException"].ToString(), "Yes", StringComparison.OrdinalIgnoreCase) == 0)
            {
                return GetMappingExceptionValue(varRow);
            }
            return GetAnswerForThisQuestionValueCombination(varRow, valueRow, repeatingSequenceNumber);
        }

        public TranslationAnswer GetMappingExceptionValue(MappingDataSet.FieldValuesRow varRow)
        {
            TranslationAnswer myAnswer = new TranslationAnswer();
            EbmtDAL.TranslationAnswer dalAnwser;
            switch (varRow.ExceptionFunctionName.Trim())
            {
                case "Get_other_unit_name_specify":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_other_unit_name_specify();
                    break;
                case "Get_N_MN_LMM_DIS_DIA_IND_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_N_MN_LMM_DIS_DIA_IND_Value(dateOfTransplant);
                    break;
                case "Get_NMN_LMM_DIS_DX_DT_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_NMN_LMM_DIS_DX_DT_Value(dateOfTransplant);
                    break;
                case "Get_R_O_P_D_O_D_D_C_H_F_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_R_O_P_D_O_D_D_C_H_F_Value(dateOfTransplant);
                    break;
                case "Get_R_O_P_D_O_D_D_C_H_D_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_R_O_P_D_O_D_D_C_H_D_Value(dateOfTransplant);
                    break;
                case "Get_HSCT_DIFF_DIS_IND_yes_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_HSCT_DIFF_DIS_IND_yes_value(dateOfTransplant);
                    break;
                case "Get_HSCT_DIFF_DIS_IND_no_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_HSCT_DIFF_DIS_IND_no_value(dateOfTransplant);
                    break;
                case "Get_Today_Date":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_Today_Date();
                    break;
                case "Get_Contact_Firstname":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_Contact_Firstname();
                    break;
                case "Get_Contact_Lastname":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_Contact_Lastname();
                    break;
                case "Get_Contact_PhoneNumber":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_Contact_PhoneNumber();
                    break;
                case "Get_Contact_Fax":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_Contact_Fax();
                    break;
                case "Get_Contact_Email":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_Contact_Email();
                    break;
                case "Get_FollowUp_Type_Period":
                    switch (currentAgnisFormDuePeriod)
                    {
                        case AgnisForm2450DuePeriods.HundredDays:
                            dalAnwser = EbmtDAL.EbmtDAL.Get_FollowUp_Type_Period(varRow.Valid_Value_Long_Name, "Day 100");
                            break;
                        case AgnisForm2450DuePeriods.SixtMonths:
                            dalAnwser = EbmtDAL.EbmtDAL.Get_FollowUp_Type_Period(varRow.Valid_Value_Long_Name,
                                                                                 "6 Months");
                            break;
                        default:
                            dalAnwser = EbmtDAL.EbmtDAL.Get_FollowUp_Type_Period(varRow.Valid_Value_Long_Name, "Annual");
                            break;
                    }
                    break;
                    //RRA 2900
                case "Get_CTRB_DTH_RSN_TP_A_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_CTRB_DTH_RSN_TP_A_Value(dateOfTransplant);
                    break;
                case "Get_CTRB_DTH_RSN_TP_B_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_CTRB_DTH_RSN_TP_B_Value(dateOfTransplant);
                    break;
                case "Get_PRM_DTH_RSN_SPEC_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_PRM_DTH_RSN_SPEC_Value(dateOfTransplant);
                    break;
                case "Get_DTH_RSN_CNF_AUTP_IND_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_DTH_RSN_CNF_AUTP_IND_Value();
                    break;
                    //RRA 2400
                case "Get_HSCT_PRIM_DIAG_DT_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_HSCT_PRIM_DIAG_DT_value(dateOfTransplant);
                    break;
                case "Get_HSCT_PRI_DIS_TYP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_HSCT_PRI_DIS_TYP_value(dateOfTransplant);
                    break;
                case "Get_TX_REL_AML_DX_DX_I_3_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_TX_REL_AML_DX_DX_I_3_value(dateOfTransplant);
                    break;
                case "Get_TX_AML_ETLGY_OCR_IND_A_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_TX_AML_ETLGY_OCR_IND_A_value(dateOfTransplant);
                    break;
                case "Get_TX_AML_ETLGY_OCR_IND_B_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_TX_AML_ETLGY_OCR_IND_B_value(dateOfTransplant);
                    break;
                case "Get_TX_AML_ETLGY_OCR_IND_C_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_TX_AML_ETLGY_OCR_IND_C_value(dateOfTransplant);
                    break;
                case "Get_AML_PR_IMTNB_TX_IND3_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_AML_PR_IMTNB_TX_IND3_value(dateOfTransplant);
                    break;
                case "Get_AML_TRN_ALEUK_STAT_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_AML_TRN_ALEUK_STAT_value(dateOfTransplant);
                    break;
                case "Get_AML_CYT_CR_Y_N_U_IND_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_AML_CYT_CR_Y_N_U_IND_value(dateOfTransplant);
                    break;
                case "Get_AML_MOL_CR_Y_N_U_IND_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_AML_MOL_CR_Y_N_U_IND_value(dateOfTransplant);
                    break;
                case "Get_AML_TRN_CR_DS_ST_CT_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_AML_TRN_CR_DS_ST_CT_value(dateOfTransplant);
                    break;
                case "Get_AML_TRN_RLPS_ST_CT_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_AML_TRN_RLPS_ST_CT_value(dateOfTransplant);
                    break;
                case "Get_TCELL_NHL_CLASS_SP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_TCELL_NHL_CLASS_SP_value(dateOfTransplant);
                    break;
                case "Get_O_DZ_DX_SPEC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_O_DZ_DX_SPEC_value(dateOfTransplant);
                    break;
                case "Get_OTHR_CNCR_CLS_DX_SPC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_OTHR_CNCR_CLS_DX_SPC_value(dateOfTransplant);
                    break;
                case "Get_O_CTYPNA_SNDRM_SPEC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_O_CTYPNA_SNDRM_SPEC_value(dateOfTransplant);
                    break;
                case "Get_OTHR_GNTC_ANM_CLS_SP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_OTHR_GNTC_ANM_CLS_SP_value(dateOfTransplant);
                    break;
                case "Get_CNG_MTB_DS_OTR_TP_SP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_CNG_MTB_DS_OTR_TP_SP_value(dateOfTransplant);
                    break;
                case "Get_IMN_DS_O_SCID_CLS_SP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_IMN_DS_O_SCID_CLS_SP_value(dateOfTransplant);
                    break;
                case "Get_IMN_DSRDR_O_CLS_SPEC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_IMN_DSRDR_O_CLS_SPEC_value(dateOfTransplant);
                    break;
                case "Get_O_CNTV_TSE_DS_TP_SPC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_O_CNTV_TSE_DS_TP_SPC_value(dateOfTransplant);
                    break;
                case "Get_VAS_OTHR_CLS_DX_SPC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_VAS_OTHR_CLS_DX_SPC_value(dateOfTransplant);
                    break;
                case "Get_ARTH_OTHR_CLS_SPEC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_ARTH_OTHR_CLS_SPEC_value(dateOfTransplant);
                    break;
                case "Get_NEURO_AUTO_O_CLS_SPC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_NEURO_AUTO_O_CLS_SPC_value(dateOfTransplant);
                    break;
                case "Get_CYTO_AUTO_O_CLS_SPC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_CYTO_AUTO_O_CLS_SPC_value(dateOfTransplant);
                    break;
                case "Get_BWL_AUTO_O_CLS_SPEC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_BWL_AUTO_O_CLS_SPEC_value(dateOfTransplant);
                    break;
                case "Get_SYS_SCD_INV_TYP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_SYS_SCD_INV_TYP_value(dateOfTransplant);
                    break;
                case "Get_SYS_LUP_ERY_INV_TYP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_SYS_LUP_ERY_INV_TYP_value(dateOfTransplant);
                    break;
                case "Get_SLE_OTR_ABDY_SPEC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_SLE_OTR_ABDY_SPEC_value(dateOfTransplant);
                    break;
                case "Get_SJO_SYN_INV_TYP_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_SJO_SYN_INV_TYP_value(dateOfTransplant);
                    break;
                case "Get_HSCT_RSRCH_CNSNT_YN_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_HSCT_RSRCH_CNSNT_YN_value();
                    break;
                case "Get_RMAB_PRP_REG_TYPE_value": // not used anymore
                    dalAnwser = EbmtDAL.EbmtDAL.Get_RMAB_PRP_REG_TYPE_value(dateOfTransplant);
                    break;
                case "Get_MAB_PRP_REG_TYPE_value": // not used anymore
                    dalAnwser = EbmtDAL.EbmtDAL.Get_MAB_PRP_REG_TYPE_value(dateOfTransplant);
                    break;
                case "Get_UNRLTD_DNR_REG_SPEC_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_UNRLTD_DNR_REG_SPEC_value(dateOfTransplant);
                    break;
                case "Get_MPS_POS_JAK2_AS_IND3_value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_MPS_POS_JAK2_AS_IND3_value(dateOfTransplant);
                    break;
                case "Get_HSC_GH_Pro_Value":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_HSC_GH_Pro_Value(dateOfTransplant);
                    break;
                case "get_ND_antigenic_value":
                    dalAnwser = EbmtDAL.EbmtDAL.get_ND_antigenic_value(dateOfTransplant);
                    break;
                case "get_ND_allelic_value":
                    dalAnwser = EbmtDAL.EbmtDAL.get_ND_allelic_value(dateOfTransplant);
                    break;
                case "OverrideValueCode":
                    dalAnwser = EbmtDAL.EbmtDAL.OverrideValueCode(varRow["Correspondence in EBMT"].ToString());
                    break;
                case "OverrideValueTo_NO":
                    dalAnwser = EbmtDAL.EbmtDAL.OverrideValueTo_NO();
                    break;
                    //RRA 2804
                case "Get_thisvalue":
                    dalAnwser = EbmtDAL.EbmtDAL.Get_thisvalue();
                    break;
                default:
                    return myAnswer;
            }
            myAnswer.hasAResponse = dalAnwser.hasAResponse;
            myAnswer.freeTextEntry = dalAnwser.freeTextEntry;
            myAnswer.textAnswer = dalAnwser.textAnswer;
            return myAnswer;
        }

        #endregion

        #region Methods used to test the expressions of each ConditionId

        //This region contains methods used for the treatment of the Condition rows stored into the table
        //MappingConditions. When there is a group of conditions, we get first the value of each subgroup.
        //The value of each subgroup of conditions is retrieved using the GetConditionValue method.
        //Example : whe have a condition expresion like this: "((A AND B) OR (C AND D)) OR E"
        //Into the MappingConditions table this expression is going to be divided in groups like this:
        //Group 1 : (A AND B) OR (C AND D)
        //Group 2 : E
        //Also Group 1 will be divided in two subgroups like this:
        //subGroup 1: (A AND B)
        //subGroup 2: (C AND D)
        //Then GetGroupValue function is going to test the value of each Group (in the last example Group1 and 2).
        //This function is going to use the GetSubGroupValue in order to get the value of each of the subgroups.
        //In the previous example it will use this function to get the values of subgroups 1 and 2.
        //Then finally the GetSubGroupValue function is going to use the function GetConditionValue in order to get
        //the value of each condition in the subgroup.

        public TranslationAnswer GetResultOfTestingConditionIdExpressions(string conditionsId, DataRow valueRow,
                                                                          MappingDataSet.FieldValuesRow varRow,
                                                                          DataSet ebmtFilteredDataSet)
        {
            //When hasConditions its True we need to take the ConditionsID in order to look for the conditions,
            //in the MappingConditions table.
            TranslationAnswer myAnswer = new TranslationAnswer();
            DataView dvConditions = new DataView(dsMappingInfo.MappingConditions);
            DataView dvConGroups = new DataView(dsMappingInfo.ConditionGroupsList);
            dvConditions.RowFilter = "[EBMT Conditions ID]='" + conditionsId + "'";
            dvConGroups.RowFilter = "[EBMT Conditions ID]='" + conditionsId + "'";

            if (dvConditions.RowFilter.IndexOf("C2400-4-086") > -1)
            {
            }
            //We get the external operator used to link the groups.
            string externalGroupRelation = GetExternalGroupRelation(dvConditions);
            bool RelationResultAnd = true;
            bool RelationResultOr = false;
            for (int i = 1; i <= dvConGroups.Count; i++)
            {
                DataView groupConditions = new DataView(dsMappingInfo.MappingConditions);
                groupConditions.RowFilter = "[EBMT Conditions ID]='" + conditionsId
                                            + "' AND ConGroup='" + i + "'";
                //We test the value of the group and using the external operator we calculate the total result.
                if (String.Compare(externalGroupRelation, "AND", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    RelationResultAnd = RelationResultAnd &&
                                        GetGroupValue(conditionsId, i, ebmtFilteredDataSet);
                }
                else if (String.Compare(externalGroupRelation, "OR", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    RelationResultAnd = false;
                    RelationResultOr = RelationResultOr
                                       || GetGroupValue(conditionsId, i, ebmtFilteredDataSet);
                }
                else if (String.Compare(externalGroupRelation, "NONE", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    if (dvConGroups.Count == 1)
                    {
                        RelationResultAnd = RelationResultAnd &&
                                            GetGroupValue(conditionsId, i, ebmtFilteredDataSet);
                    }
                    else
                    {
                        throw new TranslationException(
                            "The Conditions groups must have an external relationship operator.");
                    }
                }
            }
            if (RelationResultAnd || RelationResultOr)
            {
                myAnswer.hasAResponse = true;
                if (valueRow["Value Meaning Public ID"] != DBNull.Value)
                {
                    myAnswer.valueMeaningPublicId = (int) valueRow["Value Meaning Public ID"];
                }
                if (varRow["CopyEBMTValue"] != DBNull.Value)
                {
                    if (String.Compare(varRow.CopyEBMTValue, "No", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return myAnswer;
                    }
                    return CopyEbmtValue(varRow, ebmtFilteredDataSet);
                }
                return myAnswer;
            }
            myAnswer.hasAResponse = false;
            return myAnswer;
        }

        private bool GetGroupValue(string eBMT_Conditions_ID, int conGroup,
                                   DataSet ebmtFilteredDataSet)
        {
            bool RelationAndResult = true;
            bool RelationOrResult = false;


            DataView conSubGroups = new DataView(dsMappingInfo.ConditionsSubGroupsList);
            conSubGroups.RowFilter = "[EBMT Conditions ID]='" + eBMT_Conditions_ID + "' AND "
                                     + "ConGroup='" + conGroup + "'";
            if (conSubGroups.Count > 1)
            {
                //We need to calculate this group value using the subgroups values and GR_INREL1.
                for (int iSubGroup = 1; iSubGroup <= conSubGroups.Count; iSubGroup++)
                {
                    DataView subGroupsConditions = new DataView(dsMappingInfo.MappingConditions);
                    subGroupsConditions.RowFilter = "[EBMT Conditions ID]='" + eBMT_Conditions_ID +
                                                    "' AND ConGroup='" + conGroup +
                                                    "' AND ConSubGroup='" + iSubGroup + "'";
                    string firstInternalRelationship = subGroupsConditions[0]["GR_INREL1"].ToString();

                    if (String.Compare(firstInternalRelationship, "AND", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        RelationAndResult = RelationAndResult &&
                                            GetSubGroupValue(subGroupsConditions, ebmtFilteredDataSet);
                    }
                    else if (String.Compare(firstInternalRelationship, "OR", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        RelationAndResult = false;
                        RelationOrResult = RelationOrResult ||
                                           GetSubGroupValue(subGroupsConditions, ebmtFilteredDataSet);
                    }
                    else
                    {
                        throw new TranslationException("GR_INREL1 return an invalid value.");
                    }
                }
            }
            else if (conSubGroups.Count == 1)
            {
                //We need to calculate this group value using only one condition value.
                //CondSubGroup value in this case is 0 neal.
                DataView subGroupsConditions = new DataView(dsMappingInfo.MappingConditions);
                subGroupsConditions.RowFilter = "[EBMT Conditions ID]='" + eBMT_Conditions_ID +
                                                "' AND ConGroup='" + conGroup +
                                                "' AND ConSubGroup='0'";

                if (subGroupsConditions.Count == 1)
                {
                    //We need to calculate the value of this condition, using the external relationship.
                    string externalRelationship = subGroupsConditions[0]["GR_EXREL"].ToString();
                    MappingDataSet.MappingConditionsRow conRow =
                        (MappingDataSet.MappingConditionsRow) subGroupsConditions[0].Row;
                    if (String.Compare(externalRelationship, "AND", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        RelationAndResult = GetConditionValue(conRow, ebmtFilteredDataSet);
                    }
                    else if (String.Compare(externalRelationship, "OR", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        RelationAndResult = false;
                        RelationOrResult = GetConditionValue(conRow, ebmtFilteredDataSet);
                    }
                    else if (String.Compare(externalRelationship, "NONE", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        RelationAndResult = GetConditionValue(conRow, ebmtFilteredDataSet);
                    }
                }
                else
                {
                    throw new Exception();
                }
            }
            else
            {
                throw new Exception();
            }
            //**************************************************
            //When the group is related using an AND_Operator:
            //the instruction: return (RelationAndResult || RelationOrResult);
            //possible values:          True      ||       False   ->  True
            //possible values:          False     ||       False  ->  False
            //So in this case, this instruction is always going to return "true" if the RelationAndResult is True.
            //In the case RelationAndResult turns to False, then FALSE || FALSE will return False.
            //**************************************************
            //When the group is related with an OR_Operator:
            //the instruction: return (RelationAndResult || RelationOrResult);
            //possible values:          False      ||       True   ->  True
            //possible values:          False      ||       False  ->  False
            //is always going to return "true" if the RelationOrResult turns to True.
            //In the case the RelationOrResult stay False, then FALSE || FALSE will return False.
            //**************************************************
            return (RelationAndResult || RelationOrResult);
        }

        public bool GetSubGroupValue(DataView subGroupsConditions, DataSet ebmtFilteredDataSet)
        {
            bool RelationAndResult = true;
            bool RelationOrResult = false;

            if (subGroupsConditions.Count == 1)
            {
                //We need to calculate the value of this condition, using only GR_INREL1.
                string firstInternalRelationship = subGroupsConditions[0]["GR_INREL1"].ToString();
                MappingDataSet.MappingConditionsRow conRow =
                    (MappingDataSet.MappingConditionsRow) subGroupsConditions[0].Row;
                if (String.Compare(firstInternalRelationship, "AND", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    RelationAndResult = GetConditionValue(conRow, ebmtFilteredDataSet);
                }
                else if (String.Compare(firstInternalRelationship, "OR", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    RelationAndResult = false;
                    RelationOrResult = GetConditionValue(conRow, ebmtFilteredDataSet);
                }
            }
            else if (subGroupsConditions.Count > 1)
            {
                bool secondRelationAndResult = true;
                bool secondRelationOrResult = false;
                //We need to calculate the value of each condition belonging to this subgroup, using GR_INREL1 externally,
                //and using GR_INREL2 internally.
                string firstInternalRelationship = subGroupsConditions[0]["GR_INREL1"].ToString();
                string secondInternalRelationship = subGroupsConditions[0]["GR_INREL2"].ToString();
                foreach (DataRowView rViewSubCondition in subGroupsConditions)
                {
                    MappingDataSet.MappingConditionsRow conRow =
                        (MappingDataSet.MappingConditionsRow) rViewSubCondition.Row;
                    //We need to calculate the value of each condition belonging to this subgroup
                    //using the secondInternalRelationship as first step.
                    if (String.Compare(secondInternalRelationship, "AND", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        secondRelationAndResult = secondRelationAndResult &&
                                                  GetConditionValue(conRow, ebmtFilteredDataSet);
                    }
                    else if (String.Compare(secondInternalRelationship, "OR", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        secondRelationOrResult = secondRelationOrResult ||
                                                 GetConditionValue(conRow, ebmtFilteredDataSet);
                    }
                }
                bool secondRelationCombinedResult = String.Compare(secondInternalRelationship, "AND", StringComparison.OrdinalIgnoreCase) == 0 ? secondRelationAndResult : secondRelationOrResult;

                if (String.Compare(firstInternalRelationship, "AND", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    RelationAndResult = secondRelationCombinedResult;
                }
                else if (String.Compare(firstInternalRelationship, "OR", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    RelationAndResult = false;
                    RelationOrResult = secondRelationCombinedResult;
                }
            }
            //**************************************************
            //When the group is related using an AND_Operator:
            //the instruction: return (RelationAndResult || RelationOrResult);
            //possible values:          True      ||       False   ->  True
            //possible values:          False     ||       False  ->  False
            //So in this case, this instruction is always going to return "true" if the RelationAndResult is True.
            //In the case RelationAndResult turns to False, then FALSE || FALSE will return False.
            //**************************************************
            //When the group is related with an OR_Operator:
            //the instruction: return (RelationAndResult || RelationOrResult);
            //possible values:          False      ||       True   ->  True
            //possible values:          False      ||       False  ->  False
            //is always going to return "true" if the RelationOrResult turns to True.
            //In the case the RelationOrResult stay False, then FALSE || FALSE will return False.
            //**************************************************
            return (RelationAndResult || RelationOrResult);
        }


        private bool GetConditionValue(MappingDataSet.MappingConditionsRow mappingCondition, DataSet ebmtFilteredDataSet)
        {
            DataTable myDataTable = EbmtDAL.EbmtDAL.GetEBMTFilteredDataTable(mappingCondition, ebmtFilteredDataSet);
            string searchVal = mappingCondition["EBMT ConVar Value Code"] != DBNull.Value ? mappingCondition.EBMT_ConVar_Value_Code : "NULL";

            string comparisonOperator = mappingCondition.Operator;

            if (myDataTable != null)
            {
                if (myDataTable.Rows.Count > 0)
                {
                    for (int i = 0; i <= myDataTable.Rows.Count - 1; i++)
                    {
                        string oldValue = "";

                        if (myDataTable.Rows[i][mappingCondition.EBMT_ConVar_ID] != DBNull.Value)
                        {
                            oldValue = myDataTable.Rows[i][mappingCondition.EBMT_ConVar_ID].ToString();
                        }
                        else
                        {
                            if (searchVal == "NULL")
                            {
                                oldValue = "NULL";
                            }
                        }

                        switch (comparisonOperator)
                        {
                            case "==":
                                if (oldValue == searchVal) return true;
                                break;
                            case "<>":
                                if (oldValue != searchVal) return true;
                                break;
                            case ">":
                                if (myDataTable.Rows[i][mappingCondition.EBMT_ConVar_ID] != DBNull.Value)
                                {
                                    if (decimal.Parse(oldValue) > decimal.Parse(searchVal)) return true;
                                }
                                else
                                {
                                    return false;
                                }
                                break;
                            case "<":
                                if (myDataTable.Rows[i][mappingCondition.EBMT_ConVar_ID] != DBNull.Value)
                                {
                                    if (decimal.Parse(oldValue) < decimal.Parse(searchVal)) return true;
                                }
                                else
                                {
                                    return false;
                                }
                                break;
                            case "<=":
                                if (myDataTable.Rows[i][mappingCondition.EBMT_ConVar_ID] != DBNull.Value)
                                {
                                    if (decimal.Parse(oldValue) <= decimal.Parse(searchVal)) return true;
                                }
                                else
                                {
                                    return false;
                                }
                                break;
                            case ">=":
                                if (myDataTable.Rows[i][mappingCondition.EBMT_ConVar_ID] != DBNull.Value)
                                {
                                    if (decimal.Parse(oldValue) >= decimal.Parse(searchVal)) return true;
                                }
                                else
                                {
                                    return false;
                                }
                                break;
                            case "EXIST":
                                return true;
                            case "NOT EXIST":
                                return false;

                            default:
                                return false;
                        }
                    }
                    return false;
                }
                switch (comparisonOperator)
                {
                    case "EXIST":
                        return false;
                    case "NOT EXIST":
                        return true;
                        //Case when in the AgnisEBMTMappingDatabase in the table MappingConditions
                        //there is an operator different of EXIST or NOT EXIST that has not a valid comparing value.
                    default:
                        return false;
                }
            }
            switch (comparisonOperator)
            {
                case "EXIST":
                    return false;
                case "NOT EXIST":
                    return true;
                    //Case when in the AgnisEBMTMappingDatabase in the table MappingConditions
                    //there is an operator different of EXIST or NOT EXIST that has not a valid comparing value.
                default:
                    return false;
            }
        }

        public TranslationAnswer CopyEbmtValue(MappingDataSet.FieldValuesRow valueRow, DataSet ebmtFilteredDataSet)
        {
            TranslationAnswer myAnswer = new TranslationAnswer();
            string answerText = "";
            if (valueRow["EBMT Map Table ID"] == DBNull.Value)
            {
            }
            DataTable myDataTable = EbmtDAL.EbmtDAL.GetEBMTFilteredDataTable(valueRow.EBMT_Map_Table_ID,
                                                                             ebmtFilteredDataSet);
            if (myDataTable != null)
            {
                for (int i = 0; i <= myDataTable.Rows.Count - 1; i++)
                {
                    if (valueRow["EBMT MapVar WhatToCopy"] != null)
                    {
                        if (String.Compare(valueRow.EBMT_MapVar_WhatToCopy, "Value", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            if (valueRow["Data type"] != null)
                            {
                                if (String.Compare(valueRow.Data_type, "DATE", StringComparison.OrdinalIgnoreCase) == 0)
                                {
                                    if (myDataTable.Rows[i][valueRow.EBMT_MapVar_ID] != DBNull.Value)
                                    {
                                        DateTime myDate = (DateTime) myDataTable.Rows[i][valueRow.EBMT_MapVar_ID];
                                        answerText = myDate.ToString("yyyy-MM-dd");
                                    }
                                }
                                else
                                {
                                    answerText = myDataTable.Rows[i][valueRow.EBMT_MapVar_ID].ToString();
                                }
                            }
                            else
                            {
                                answerText = myDataTable.Rows[i][valueRow.EBMT_MapVar_ID].ToString();
                            }
                        }
                        else
                        {
                            if (myDataTable.Rows[i][valueRow.EBMT_MapVar_ID].ToString() != "")
                            {
                                answerText = EbmtDAL.EbmtDAL.GetEBMTVariableValueDescription(valueRow.EBMT_MapVar_ID,
                                                                                             valueRow.
                                                                                                 EBMT_MapVar_Values_Group_ID,
                                                                                             int.Parse(
                                                                                                 myDataTable.Rows[i][
                                                                                                     valueRow.
                                                                                                         EBMT_MapVar_ID]
                                                                                                     .ToString()));
                            }
                            else
                            {
                                answerText = "Not answered"; //RRA - pre Override code
                            }
                        }
                    }
                    else
                    {
                        answerText = myDataTable.Rows[i][valueRow.EBMT_MapVar_ID].ToString();
                    }
                }
            }
            myAnswer.freeTextEntry = true;
            myAnswer.hasAResponse = true;
            myAnswer.textAnswer = answerText;
            return myAnswer;
        }

        public static string GetExternalGroupRelation(DataView dvConditions)
        {
            if (dvConditions.Count == 0)
            {
            }

            DataRowView myRowView = dvConditions[0];
            MappingDataSet.MappingConditionsRow myRow = (MappingDataSet.MappingConditionsRow) myRowView.Row;
            return myRow.GR_EXREL;
        }

        #endregion

        #endregion

        #region XML related methods

        public static string SerializeObjectToXmlString(object obj)
        {
            XmlTextWriter writer = new XmlTextWriter(new MemoryStream(), Encoding.UTF8);
            writer.Formatting = Formatting.Indented;
            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            serializer.Serialize(writer, obj);
            MemoryStream stream = (MemoryStream) writer.BaseStream;
            string xmlString = UTF8ByteArrayToString(stream.ToArray());
            return xmlString;
        }

        public static string UTF8ByteArrayToString(Byte[] characters)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            return encoding.GetString(characters);
        }

        #endregion
    }

    #endregion
}